package com.base.cn.platform.os.service.course.cou;

import com.base.cn.platform.os.common.constants.ConfigName;
import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.service.CommonSetCreateUserDataService;
import com.base.cn.platform.os.common.service.CommonSetSubjectDataService;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.common.utils.course.CourseType;
import com.base.cn.platform.os.common.utils.price.PriceUtils;
import com.base.cn.platform.os.dao.course.cou.CourseDao;
import com.base.cn.platform.os.entity.classes.Classes;
import com.base.cn.platform.os.entity.course.catalog.CourseCatalog;
import com.base.cn.platform.os.entity.course.cou.Course;
import com.base.cn.platform.os.entity.course.cou.CourseCondition;
import com.base.cn.platform.os.entity.course.cou.buy.CourseBuyRecord;
import com.base.cn.platform.os.entity.course.cou.packageCou.PackageCourse;
import com.base.cn.platform.os.entity.course.cou.record.CoursePlayRecord;
import com.base.cn.platform.os.entity.course.count.CourseSumCount;
import com.base.cn.platform.os.service.classes.ClassesBiz;
import com.base.cn.platform.os.service.course.catalog.CourseCatalogBiz;
import com.base.cn.platform.os.service.course.cou.buy.CourseBuyRecordBiz;
import com.base.cn.platform.os.service.course.cou.packageCou.PackageCourseBiz;
import com.base.cn.platform.os.service.course.cou.record.CoursePlayRecordBiz;
import com.base.cn.platform.os.service.exam.record.ExamRecordService;
import com.base.cn.platform.os.service.manage.config.SysConfigService;
import com.base.cn.platform.os.service.manage.op.groom.OpGroomDataService;
import com.base.cn.platform.os.service.manage.subject.SubjectService;
import com.base.cn.platform.os.service.manage.sysUser.SysUserService;
import com.base.cn.platform.os.service.manage.teacher.SysTeacherService;
import com.base.cn.platform.os.service.manage.user.member.CusUserMemberBuyRecordService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 课程Biz
 *
 * @author s.li
 * @create 2018-04-17-10:54
 */
@Service
public class CourseBiz extends BaseBiz<Course, CourseDao> {
    @Autowired
    private CommonSetCreateUserDataService<Course> commonSetCreateUserDataService;
    @Autowired
    private CommonSetSubjectDataService<Course> commonSetSubjectDataService;
    @Autowired
    private SysTeacherService sysTeacherService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SubjectService subjectService;
    @Autowired
    private CourseDao courseDao;
    @Autowired
    private CourseProfileBiz courseProfileBiz;
    @Autowired
    private PackageCourseBiz packageCourseBiz;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private ClassesBiz classesBiz;
    @Autowired
    private CourseBuyRecordBiz courseBuyRecordBiz;
    @Autowired
    private CusUserMemberBuyRecordService cusUserMemberBuyRecordService;
    @Autowired
    private OpGroomDataService opGroomDataService;
    @Autowired
    private CoursePlayRecordBiz coursePlayRecordBiz;
    @Autowired
    private CourseCatalogBiz courseCatalogBiz;
    @Autowired
    private Environment environment;
    @Autowired
    private ExamRecordService examRecordService;

    /**
     * 复制课程数据
     * @param course 课程对象
     */
    public Course copyCourse(Course course){
        course.setStatus(0);
        course.setCourseName("复制-"+course.getCourseName());
        course.setId(null);
        course.setContextStatus(1);
        course.setCreateTime(null);
        course.setUpdateTime(null);
        course.setCreateClass(0);
        this.save(course);
        //创建课程扩展数据
        courseProfileBiz.createCourseProfile(course.getId());
        return course;
    }


    /**
     * 获取课程数量
     *
     * @param condition 查询条件
     * @return 数量
     */
    public BigDecimal getCourseCount(CourseCondition condition) {
        return this.count(this.getWhereSql(condition));
    }

    /**
     * 保存课程数据
     *
     * @param course 课程对象
     * @return 返回课程成功的课程对象
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public Course saveCourse(Course course) {
        if (DataUtil.idIsNotNull(course.getId())) {//修改
            Course _course = this.findById(course.getId());
            _course.setCourseName(course.getCourseName());//课程名
            _course.setOrPrice(course.getOrPrice());//原价
            _course.setRealPrice(course.getRealPrice());//实销价格
            _course.setMemberCourse(course.getMemberCourse());//是否是会员课程
            _course.setMemberPrice(course.getMemberPrice());//会员价格
            _course.setValidType(course.getValidType());// 课程期限类型
            _course.setValidDay(course.getValidDay());//有效天数
            _course.setValidTime(course.getValidTime());//到期时间
            _course.setImageJson(course.getImageJson());//课程图片
            _course.setScorePercent(course.getScorePercent());//得分率
            _course.setTeacherIds(course.getTeacherIds());//讲师ID串
            if (course.getValidType() == 2) {
                _course.setDontBuyTime(course.getDontBuyTime());
            }
            if (_course.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())) {
                _course.setCourseNum(course.getCourseNum());
                _course.setUseNum(course.getUseNum());
            }
            //验证课程是否处于非上架状态
            if(_course.getStatus()!=1){
                _course.setSubjectIds(course.getSubjectIds());
            }
            _course.setBuyNum(course.getBuyNum());//可购买人数（招生数）
            _course.setInitBuyNum(course.getInitBuyNum());//初始化可购买人数
            _course.setTestNum(course.getTestNum());//可视听人数
            _course.setYear(course.getYear());//所属年份
            _course.setAllow(course.getAllow());// 允许平台分销代卖
            _course.setSort(course.getSort());
            _course.setLimitDate(course.getLimitDate());
            _course.setOpenTime(course.getOpenTime());
            _course.setEndTime(course.getOpenTime());
            _course.setAudition(course.getAudition());
            this.updateById(_course, null);
        } else {//添加
            course.setContextStatus(1);//内容状态 1.未完成 2.已完成 默认未完成
            course.setStudyLimit(1);//默认无顺序
            this.save(course);
            //创建课程扩展数据
            courseProfileBiz.createCourseProfile(course.getId());
        }
        return course;
    }

    /**
     * 保存课程描述信息
     *
     * @param course 课程数据对象
     * @return 保存后的课程对象
     */
    public Course saveCourseInfo(Course course) {
        if (DataUtil.idIsNotNull(course.getId())) {
            Course _course = this.findById(course.getId());
            _course.setImageJson(course.getImageJson());//课程图片信息
            _course.setSummary(course.getSummary());//课程简介
            _course.setDetails(course.getDetails());//课程详情
            _course.setInitBuyNum(course.getInitBuyNum());//购买人数
            _course.setYear(course.getYear());//课程年份
            if (_course.getCreateClass()== 0 && course.getCreateClass()==1) {
                Classes classes = new Classes();
                classes.setName(_course.getCourseName() + "课程班级");
                classes.setSummary(_course.getSummary());
                //设置班级默认封面图
                String staticPath = environment.getProperty("static.path");
                staticPath += "/front/web/v3/img/default/default-class.jpg";
                HashMap<String, Object> objectObjectHashMap = new HashMap<>();
                Map<String,String> urlMap = new TreeMap<>();
                urlMap.put("small",staticPath);
                objectObjectHashMap.put("pcUrlMap",urlMap);
                objectObjectHashMap.put("mobileUrlMap",urlMap);
                Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
                classes.setImageJson(gson.toJson(objectObjectHashMap));
                classes.setSubjectIds(_course.getSubjectIds());
                classes.setClassesType(1);
                classes.setCourseId(_course.getId());
                classes.setFull(2);
                classes.setStatus(1);
                classes.setHeadmasterIds(_course.getTeacherIds());
                classes.setCreateUserId(_course.getCreateUserId());
                //同时使用班级
                classesBiz.saveClasses(classes);
            }
            _course.setCreateClass(course.getCreateClass());
            this.updateById(_course, null);
            return _course;
        }
        return course;
    }

    /**
     * 查询课程详情
     *
     * @param courseId       课程ID
     * @param userId         用户ID
     * @param onLimit         是否有限制，true没有，false有
     * @param setPuyStatus   是否设置购买状态数据
     * @param teacherData    是否设置讲师数据
     * @param subjectData    是否设置专业数据
     * @param sysUserData    是否设置创建人数据
     * @param setProfileData 是否设置扩展数据
     * @param setLiveCourseNodesData 是否设置课程直播节点数据
     * @return Course
     */
    public Course findCourseById(BigDecimal courseId,
                                 BigDecimal userId,
                                 boolean onLimit,
                                 boolean setPuyStatus,
                                 boolean teacherData, boolean subjectData,
                                 boolean sysUserData, boolean setProfileData,boolean setLiveCourseNodesData) {

        Course course = this.findCourseById(courseId, userId, onLimit, setPuyStatus, teacherData, subjectData,
                sysUserData, setProfileData, false, setLiveCourseNodesData);
        if (course.getValidType()==2&&ObjectUtils.isNotEmpty(course.getDontBuyTime())){
            if (course.getDontBuyDate() <= 0) {
                course.setStatus(5);
            }
        }
        return course;
    }

    /**
     * 查询课程详情
     *
     * @param courseId       课程ID
     * @param userId         用户ID
     * @param onLimit         是否有限制，true没有，false有
     * @param setPuyStatus   是否设置购买状态数据
     * @param teacherData    是否设置讲师数据
     * @param subjectData    是否设置专业数据
     * @param sysUserData    是否设置创建人数据
     * @param setProfileData 是否设置扩展数据
     * @param setLiveCourseNodesData 是否设置课程直播节点数据
     * @return Course
     */
    public Course findCourseById(BigDecimal courseId,
                                 BigDecimal userId,
                                 boolean onLimit,
                                 boolean setPuyStatus,
                                 boolean teacherData, boolean subjectData,
                                 boolean sysUserData, boolean setProfileData,
                                 boolean setPackageCourseData,
                                 boolean setLiveCourseNodesData) {
        Course course = this.findCourseById(onLimit,courseId, teacherData, subjectData, sysUserData, setProfileData,setLiveCourseNodesData);
        if (StringUtils.isEmpty(course)){
            return course;
        }
        //设置购买状态
        this.setPuyStatus(course,userId,setPuyStatus,setPackageCourseData);
        List<PackageCourse> packageCourseList = packageCourseBiz.findPackageCourseByPackageId(courseId,true);
        packageCourseList = packageCourseList.stream().filter(v -> v.getCourse()!=null).collect(Collectors.toList());
        course.setPackageCourseList(packageCourseList);
        return course;
    }

    /**
     * 通过ID，查询课程对象
     *
     * @param onLimit        是否有限制
     * @param courseId       课程ID
     * @param teacherData    是否设置讲师数据
     * @param subjectData    是否设置专业数据
     * @param sysUserData    是否设置创建人数据
     * @param setProfileData 是否设置扩展数据
     * @param setLiveCourseNodesData 是否设置课程直播节点数据
     * @return Course
     */
    public Course findCourseById(boolean onLimit,BigDecimal courseId, boolean teacherData,
                                 boolean subjectData, boolean sysUserData, boolean setProfileData,
                                 boolean setLiveCourseNodesData) {
        Course course = this.findCourseById(onLimit,courseId, teacherData, subjectData, sysUserData);
        course = courseProfileBiz.setCourseProfileData(course, setProfileData);
        if(setLiveCourseNodesData){
            courseCatalogBiz.setLiveCourseNodesData(course,true);
        }
        return course;
    }

    /**
     * 通过ID，查询课程对象
     *
     * @param courseId    课程ID
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return Course
     */
    public Course findCourseById(boolean onLimit,BigDecimal courseId, boolean teacherData, boolean subjectData, boolean sysUserData) {
        CourseCondition condition = new CourseCondition();
        condition.setIds(courseId.toString());
        condition.setCount(1);//只查询一条数据
        condition.setOnLimit(onLimit);
        String whereSql = this.getWhereSql(condition);
        Course course = this.findOne(whereSql,null);
        if(course !=null){
            this.setCourseExData(course,teacherData,subjectData,sysUserData);
        }
        return course;
    }

    /**
     * 通过Ids，查询课程数据列表
     *
     * @param courseIds      课程查询条件
     * @param teacherData    是否设置讲师数据
     * @param subjectData    是否设置专业数据
     * @param sysUserData    是否设置创建人数据
     * @param setProfileData 是否设置课程扩展数据
     * @return Map<BigDecimal   ,   Course>
     */
    public Map<BigDecimal, Course> findCourseToMapByIds(String courseIds, boolean teacherData, boolean subjectData, boolean sysUserData, boolean setProfileData) {
        if(StringUtils.isNotEmpty(courseIds)){
            CourseCondition courseCondition = new CourseCondition();
            courseCondition.setIds(courseIds);
            List<Course> courseList = this.find("id in (" + courseIds + ")", null, this.getColumnName());
            courseList = this.setCourseTeacherData(courseList, teacherData);
            courseList = commonSetSubjectDataService.setSubjectData(subjectService, courseList, subjectData);
            courseList = commonSetCreateUserDataService.setSysUserData(sysUserService, courseList, sysUserData);
            courseList = courseProfileBiz.setCourseProfileData(courseList, setProfileData);
            //设置直播课程节点
            courseCatalogBiz.setLiveCourseNodesData(courseList,true);
            if (ObjectUtils.isNotEmpty(courseList)) {
                return courseList.stream().collect(Collectors.toMap(e -> e.getId(), e -> e));
            }
        }
        return null;
    }

    /**
     * 通过父级专业id串，查询专业下课程（每个专业4条数据）
     * @param placeKey 推荐位KEY
     * @param profileData 是否设置课程扩展对象
     * @param teacherData 是否设置老师数据
     * @return List< Map<String , Object>> 专业列表
     */
    public List<Map<String,Object>> findRecommendSubjectCourseList(String placeKey,boolean profileData,boolean teacherData){
        Map<String,Object> _subject = new HashMap<>();
        _subject.put("placeKey",placeKey);
        _subject.put("status",1);
        List<Map<String,Object>> subjectList = subjectService.findSubjectList(_subject);
        if(StringUtils.isNotEmpty(subjectList)){
            CourseCondition courseCondition = new CourseCondition();
            courseCondition.setStatus(1);
            courseCondition.setCount(4);
            subjectList.forEach(subject->{
                String subjectId = subject.get("id").toString();
                courseCondition.setSubjectIds(subjectId);
                List<Course> courseList = this.findCourseList(courseCondition,teacherData,false,false,profileData);
                subject.put("courseList",courseList);
            });
        }
        return subjectList;
    }


    /**
     * 通过Ids，查询课程数据列表
     *
     * @param courseIds   课程查询条件
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return Map<BigDecimal   ,   Course>
     */
    public Map<BigDecimal, Course> findCourseToMapByIds(String courseIds, boolean teacherData, boolean subjectData, boolean sysUserData) {
        return this.findCourseToMapByIds(courseIds, teacherData, subjectData, sysUserData, true);
    }

    /**
     * 查询套餐课程详情
     *
     * @param courseId 课程ID
     * @return Course
     */
    public Course findPackageInfo(BigDecimal courseId) {
        Course course = this.findCourseById(false,courseId, false, false, false);
        if (ObjectUtils.isNotEmpty(course) && course.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())) {
            List<PackageCourse> packageCourseList = packageCourseBiz.findPackageCourseByPackageId(courseId, true);
            course.setPackageCourseList(packageCourseList);
        }
        return course;
    }

    /**
     * 通过多条件，查询课程数据列表
     *
     * @param condition   课程查询条件
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @param setProfileData 是否设置扩展数据
     * @return List<Course>
     */
    public List<Course> findCourseList(CourseCondition condition, boolean teacherData, boolean subjectData, boolean sysUserData, boolean setProfileData) {
        List<Course> courseList = this.findCourseList(condition, teacherData, subjectData, sysUserData);
        if (ObjectUtils.isNotEmpty(courseList) && setProfileData) {
            courseProfileBiz.setCourseProfileData(courseList, setProfileData);
        }
        return courseList;
    }

    /**
     * 通过多条件，查询课程数据列表
     *
     * @param condition   课程查询条件
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return List<Course>
     */
    public List<Course> findCourseList(CourseCondition condition, boolean teacherData, boolean subjectData, boolean sysUserData) {
        String whereSql = getWhereSql(condition);
        List<Course> courseList = this.find(whereSql, condition.getCount(), this.getColumnName());
        courseList = this.setCourseExData(courseList, teacherData, subjectData, sysUserData);
        return courseList;
    }

    /**
     * 获取套餐下的课程列表
     * @param courseIds 课程ID串
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return 套餐下的课程列表
     */
    public List<Course> findPackageCourseList(String courseIds,boolean teacherData, boolean subjectData, boolean sysUserData){
        List<Course> courseList = this.find("id in ("+courseIds+")",null,this.getColumnName());
        courseList = this.setCourseExData(courseList, teacherData, subjectData, sysUserData);
        return courseList;
    }

    /**
     * 分页查询课程列表
     *
     * @param condition      查询条件
     * @param page           分页条件
     * @param teacherData    是否设置讲师数据
     * @param subjectData    是否设置专业数据
     * @param sysUserData    是否设置创建人数据
     * @param setProfileData 是否设置课程扩展数据
     * @return PageInfo<Course>
     */
    public PageInfo<Course> findCoursePage(CourseCondition condition, Pagination page,
                                           boolean teacherData,
                                           boolean subjectData,
                                           boolean sysUserData,
                                           boolean setProfileData,
                                           boolean setLiveCourseNodesData) {
        if (StringUtils.isNotEmpty(condition.getTeacherName())) {
            Map<String, Object> params = Collections.singletonMap("teacherName", condition.getTeacherName());
            List<Map<String, Object>> teacherList = sysTeacherService.findSysTeacherList(params, false, false, false, false, false);
            if (ObjectUtils.isEmpty(teacherList)) {
                return new PageInfo<>();
            }
            String teacherIds = DataUtil.joining(teacherList, (v) -> v.get("id"));
            condition.setTeacherIds(teacherIds);
        }
        if(!ObjectUtils.isNotEmpty(condition.getOrderType())||condition.getOrderType()==0){
            condition.setOrderType(5);
        }
        PageInfo<Course> coursePageInfo = this.findCoursePage(condition, page, teacherData, subjectData, sysUserData);
        courseProfileBiz.setCourseProfileData(coursePageInfo.getList(), setProfileData);
        //设置直播课程节点
        courseCatalogBiz.setLiveCourseNodesData(coursePageInfo.getList(),setLiveCourseNodesData);
        return coursePageInfo;
    }

    /**
     * 分页查询课程列表
     *
     * @param condition   查询条件
     * @param page        分页条件
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return
     */
    public PageInfo<Course> findCoursePage(CourseCondition condition, Pagination page,
                                           boolean teacherData, boolean subjectData, boolean sysUserData) {
        PageInfo<Course> coursePageInfo = null;
        if (condition.getType() == 1 || condition.getType() == 3 || condition.getType() == 4) {
            if(condition.getType()==3){
                condition.setCourseTypeKey(CourseType.COURSE_TYPE_LIVE.getKey());
            }
            if(condition.getType()==4){
                condition.setCourseTypeKey(CourseType.COURSE_TYPE_SMALL.getKey());
            }
            String whereSql = getWhereSql(condition);
            coursePageInfo = this.findPage(whereSql, page, this.getColumnName());
        } else if (condition.getType() == 2) {
            coursePageInfo = this.findPackageSelectCourseList(condition, page, teacherData, subjectData, sysUserData);
        }
        //设置扩展数据
        coursePageInfo.setList(this.setCourseExData(coursePageInfo.getList(), teacherData, subjectData, sysUserData));
        return coursePageInfo;
    }

    /**
     * 查询套餐选择课程列表
     *
     * @param condition   查询条件
     * @param page        分页条件
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置专业数据
     * @param sysUserData 是否设置创建人数据
     * @return PageInfo<Course>
     */
    private PageInfo<Course> findPackageSelectCourseList(CourseCondition condition, Pagination page,
                                                         boolean teacherData, boolean subjectData, boolean sysUserData) {
        PageHelper.startPage(page.getCurrentPage(), page.getPageSize());
        if(StringUtils.isNotEmpty(condition.getSubjectIds())){
            condition.setSubjectSql(StringUtils.getSubjectSql("subjectIds",condition.getSubjectIds()));
        }
        Page<Course> coursePage = courseDao.findPackageSelectCourseList(Course.class, condition);
        PageInfo<Course> coursePageInfo = new PageInfo<>(coursePage);
        //设置扩展数据
        coursePageInfo.setList(this.setCourseExData(coursePageInfo.getList(), teacherData, subjectData, sysUserData));
        return coursePageInfo;
    }

    /**
     * 修改完结状态
     *
     * @param courseIds 课程ID串，多个ID以“,”隔开
     */
    public void updateContextStatus(String courseIds) {
        if (StringUtils.isNotEmpty(courseIds)) {
            courseIds = StringUtils.subHeadTailString(courseIds, ",");
            if (StringUtils.isNotEmpty(courseIds)) {
                Course course = new Course();
                course.setContextStatus(2);
                this.updateByWhereSql(course, " id in (" + courseIds + ")");
            }
        }
    }

    /**
     * 修改课程状态
     *
     * @param updateList 要修改的课程列表
     * @param deleteList 要真删除的课程数据
     * @param status     状态，1下架，2下架，3删除
     * @param addList
     * @param subList
     */
    @Transactional(rollbackFor = IllegalArgumentException.class)
    public void updateCourseStatus(List<Course> updateList, List<Course> deleteList, int status, List<Map<BigDecimal, String>> addList, List<Map<BigDecimal, String>> subList) {
        String updateIds = null;
        String packageIds = null;
        String allDeleteIds = "";
        if (status == 1 || status == 2) {
            if (ObjectUtils.isNotEmpty(updateList)) {//修改的
                updateIds = updateList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                if(status==2){//下架的时间
                    allDeleteIds += updateIds;
                }
                //只有在上架的时候再执行
                if (status == 1) {
                    //以未上架过、且是套餐的课程为条件进行分组
                    Map<Boolean, List<Course>> courseListMap = updateList.stream().collect(Collectors.groupingBy(e -> e.getStatus().intValue() == 0 && e.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())));
                    //获取是套餐类型的，且未上架过的套餐课程
                    List<Course> pCourseList = courseListMap.get(true);
                    if (ObjectUtils.isNotEmpty(pCourseList)) {
                        packageIds = pCourseList.stream().map(e -> e.getId().toString()).distinct().collect(Collectors.joining(","));
                    }
                }
            }
        }
        if (status == 3) {//删除状态
            if (ObjectUtils.isNotEmpty(updateList)) {//修改的成删除状态的ID串
                updateIds = updateList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                if(StringUtils.isNotEmpty(allDeleteIds)){
                    allDeleteIds += "," + updateIds;
                }else{
                    allDeleteIds = updateIds;
                }
            }
            if (ObjectUtils.isNotEmpty(deleteList)) {//真删除的
                String deleteIds = deleteList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                this.deleteWhereSql(" id in (" + deleteIds + ")");
                courseProfileBiz.deleteWhereSql(" id in ("+deleteIds+")");
                if(StringUtils.isNotEmpty(allDeleteIds)){
                    allDeleteIds += "," + deleteIds;
                }else{
                    allDeleteIds = deleteIds;
                }
            }
        }
        if (StringUtils.isNotEmpty(updateIds)) {//执行修改
            if (StringUtils.isNotEmpty(packageIds) && status == 1) {
                //修改套餐课程包含的课程类型
                this.setPackageCourseTypes(packageIds);
            }
            Course course = new Course();
            course.setStatus(status);
            this.updateByWhereSql(course, " id in (" + updateIds + ")");
        }
        //修改讲师的包含课程量
        Map<String, List<Map<BigDecimal, String>>> teacherCourseNumData = new HashMap<>();
        teacherCourseNumData.put("add", addList);
        teacherCourseNumData.put("sub", subList);
        sysTeacherService.updateTeacherCourseNum(teacherCourseNumData);
        if(StringUtils.isNotEmpty(allDeleteIds)){//删除推荐位的课程
            opGroomDataService.deleteGroomDataByDataIdAndDataType(allDeleteIds,"COURSE");
        }
    }

    /**
     * 设置套餐课程的包含课程的类型(用于套餐第一次上架的时候)
     *
     * @param packageIds 套餐课程ID串
     */
    public void setPackageCourseTypes(String packageIds) {
        //套餐课程列表
        List<Course> pCourseList = new ArrayList<>();
        if (StringUtils.isNotEmpty(packageIds)) {
            PackageCourse packageCourse = new PackageCourse();
            packageCourse.setPackageIds(packageIds);
            List<PackageCourse> packageCourseList = packageCourseBiz.findList(packageCourse, false);
            if (ObjectUtils.isNotEmpty(packageCourseList)) {
                //通过套餐ID分组
                Map<BigDecimal, List<PackageCourse>> packageCourseMap = packageCourseList.stream().collect(Collectors.groupingBy(e -> e.getPackageId()));
                packageCourseMap.forEach((k, v) -> {
                    String containNodeType = "";
                    //通过课程类型是否为空null分组
                    Map<Boolean, List<PackageCourse>> packageCourseListMap = v.stream().collect(Collectors.groupingBy(e -> StringUtils.isNotEmpty(e.getCourseTypeKey())));
                    if (ObjectUtils.isNotEmpty(packageCourseListMap)) {
                        //获取课程类型不为null的套餐课程记录数据列表
                        List<PackageCourse> _packageCourseList = packageCourseListMap.get(true);
                        if (ObjectUtils.isNotEmpty(_packageCourseList)) {
                            Set<String> typeSet = new HashSet<>();
                            _packageCourseList.forEach(e -> {
                                String courseTypeKey = e.getCourseTypeKey();
                                if (ObjectUtils.isNotEmpty(courseTypeKey)) {
                                    if (CourseType.COURSE_TYPE_COLUMNS.getKey().equals(courseTypeKey)) {
                                        typeSet.add(CourseType.COURSE_TYPE_COLUMNS.getValue());
                                    }
                                    if (CourseType.COURSE_TYPE_VIDEO.getKey().equals(courseTypeKey)) {
                                        typeSet.add(CourseType.COURSE_TYPE_VIDEO.getValue());
                                    }
                                    if (CourseType.COURSE_TYPE_LIVE.getKey().equals(courseTypeKey)) {
                                        typeSet.add(CourseType.COURSE_TYPE_LIVE.getValue());
                                    }
                                }
                            });

                            if (ObjectUtils.isNotEmpty(typeSet)) {
                                containNodeType = typeSet.stream().map(e -> e).collect(Collectors.joining("、"));
                            }
                        }
                    }
                    Course course = new Course();
                    course.setContainNodeType(containNodeType);
                    course.setId(k);
                    pCourseList.add(course);
                });

            }
        }
        //更新套餐购买的课程类型
        if (ObjectUtils.isNotEmpty(pCourseList)) {
            this.updateBatch(pCourseList);
        }
    }



    /**
     * 分页查询课程列表
     *
     * @param condition   查询条件
     * @param page        分页条件
     * @return
     */
    public PageInfo<Course> findCoursePracticePage(CourseCondition condition, Pagination page) {

        PageInfo<Course> coursePage = this.findCoursePage(condition, page, false, false, false);
        //设置该课程随堂练习的练习总人数和
        this.setCoursePractice(coursePage.getList());
        return coursePage;
    }
    //============================================================================================

    private void setCoursePractice(List<Course> courses){
        for(Course course:courses){
            HashMap<Object, Object> param = new HashMap<>();
            param.put("courseId",course.getId());
            param.put("courseScoreRate",course.getScorePercent());
            Map map = examRecordService.queryPracticePassNumber(param);
            if(ObjectUtils.isNotEmpty(map.get("passNumber"))){
                course.setPracticePassNumber(Integer.valueOf(map.get("passNumber").toString()));
            }else{
                course.setPracticePassNumber(0);
            }
            if(ObjectUtils.isNotEmpty(map.get("headcount"))){
                course.setPracticeHeadcount(Integer.valueOf(map.get("headcount").toString()));
            }else{
                course.setPracticeHeadcount(0);
            }
        }

    }


    /**
     * 设置购买状态
     * @param course 课程对象
     * @param userId 用户ID
     * @param setBuyStatus 设置购买状态
     * @param setPackageCourseData 设置套餐下的课程数据（用于套餐课程）
     */
    private void setPuyStatus(Course course,BigDecimal userId,boolean setBuyStatus,boolean setPackageCourseData){
        Map<String, Object> buyStatus = new HashMap<>();
        //设置课程购买状态数据
        if (ObjectUtils.isNotEmpty(course)) {
            CourseBuyRecord record = null;
            if(DataUtil.idIsNotNull(userId)){//检测用户购买课程的记录
                record = courseBuyRecordBiz.checkUserBuyCourse(userId, course.getId());
            }
            if (ObjectUtils.isNotEmpty(record)) {//已购买
                //设置课程对象
                record.setCourse(course.clone());
                //设置套餐课程下的课程数据
                courseBuyRecordBiz.setPackageCourseData(record, setPackageCourseData);
                buyStatus.put("buy", true);//已有购买记录
                buyStatus.put("record", record);//购买记录对象
                //设置课程最新播放记录
                List<CoursePlayRecord> playRecordList = coursePlayRecordBiz.find(" userId = "+userId+" and buyCourseId = "+course.getId()+" order by updateTime desc",null,null);
                if(ObjectUtils.isNotEmpty(playRecordList)){
                    course.setLastCoursePlayRecord(playRecordList.get(0));
                }
            }
            //获取用户的会员权限
            boolean memberUser = false;
            if(DataUtil.idIsNotNull(userId)) {//检测用户会员权限
                //获取用户的会员权限
                memberUser = cusUserMemberBuyRecordService.checkUserUseMemberPrice(userId);
            }
            //获取售卖方式配置
            TreeMap<String, String> configMap = sysConfigService.getSysConfigContext(ConfigName.SALE);
            //售卖方式
            String selaSwitch = configMap.get("selaSwitch");
            buyStatus = PriceUtils.handleCourseOrExamPriceData(buyStatus,selaSwitch,course.getMemberCourse(),course.getRealPrice(),course.getMemberPrice(),memberUser);
        }
        //设置数据
        course.setCourseBuyStatus(buyStatus);
    }

    /**
     * 获取课程查询条件
     *
     * @param condition 条件对象
     * @return 返回查询条件
     */
    private String getWhereSql(CourseCondition condition) {

        StringBuilder whereSql = new StringBuilder("`status`!=3 and courseTypeKey !='' and courseTypeKey is not null");
        if(condition.isOnLimit()){
            whereSql.delete(0,whereSql.length());
            whereSql.append("1=1");
        }
        if (ObjectUtils.isNotEmpty(condition)) {
            if (DataUtil.idIsNotNull(condition.getId())) {
                whereSql.append(" and id = ").append(condition.getId());
            }
            if (StringUtils.isNotEmpty(condition.getIds())) {
                whereSql.append(" and id in(").append(StringUtils.subHeadTailString(condition.getIds(), ",")).append(")");
            }
            if (StringUtils.isNotEmpty(condition.getCourseTypeKey())) {
                whereSql.append(" and courseTypeKey ='").append(condition.getCourseTypeKey()).append("'");
            }
            if (StringUtils.isNotEmpty(condition.getNotCourseTypeKey())) {
                whereSql.append(" and courseTypeKey !='").append(condition.getNotCourseTypeKey()).append("'");
            }
            if(StringUtils.isNotEmpty(condition.getNotCourseTypeKeys())){
                whereSql.append(" and courseTypeKey not in (").append(condition.getNotCourseTypeKeys()).append(")");
            }
            if (StringUtils.isNotEmpty(condition.getCourseName())) {
                whereSql.append(" and courseName like '%").append(condition.getCourseName()).append("%'");
            }
            if (condition.getAllow()!=null){
                whereSql.append(" and allow=").append(condition.getAllow());
            }
            if (ObjectUtils.isNotEmpty(condition.getStatus())) {
                if (condition.getStatus().intValue() == 4) {
                    whereSql.append(" and status=0");
                } else {
                    whereSql.append(" and status=").append(condition.getStatus());
                }
            }
            if (condition.isNotExpire()) {//查询未过期的课程
                whereSql.append(" and (validType=1 or (validType=2 and validTime > now())) ");
            }
            if (StringUtils.isNotEmpty(condition.getSubjectIds()) &&
                    !CourseType.COURSE_TYPE_PACKAGE.getKey().equals(condition.getCourseTypeKey())) {
                whereSql.append(StringUtils.getSubjectSql("subjectIds", condition.getSubjectIds()));
                whereSql.append(" and courseTypeKey !='").append(CourseType.COURSE_TYPE_PACKAGE.getKey()).append("'");
            }
            if (StringUtils.isNotEmpty(condition.getYear())) {
                whereSql.append(" and year = '").append(condition.getYear()).append("'");
            }
            if (ObjectUtils.isNotEmpty(condition.getNoNodeNum())) {
                whereSql.append(" and nodeNum >0  ");
            }
            if (StringUtils.isNotEmpty(condition.getTeacherIds())) {
                String[] array = StringUtils.subHeadTailString(condition.getTeacherIds(), ",").split(",");
                StringJoiner joiner = new StringJoiner(" or ");
                for (String s : array) {
                    joiner.add(" ( teacherIds like '%," + s + ",%' )");
                }
                whereSql.append(" and (").append(joiner).append(")");
            }
            if (StringUtils.isNotEmpty(condition.getCourseNames())) {
                String[] array = StringUtils.subHeadTailString(condition.getCourseNames(), ",").split(",");
                StringJoiner nameJoiner = new StringJoiner(" or ");
                for (String n : array) {
                    nameJoiner.add(" ( courseName like '%" + n + "%' )");
                }
                whereSql.append(" and (").append(nameJoiner).append(")");
            }
             if (condition.getOrderType() == 1) {//更新时间倒序排序
                whereSql.append(" order by updateTime desc");
            } else if (condition.getOrderType() == 2) {//更新时间升序排序
                whereSql.append(" order by updateTime asc");
            } else if (condition.getOrderType() == 3) {//价格倒序排序
                    whereSql.append(" order by realPrice desc");
            } else if (condition.getOrderType() == 4) {//价格升序排序
                    whereSql.append(" order by realPrice asc");
            } else if (condition.getOrderType() == 5) {//排序字段排序
                whereSql.append(" order by sort desc");
            } else {
                whereSql.append(" order by id desc");
            }
        }
        return whereSql.toString();
    }

    /**
     * 设置课程扩展数据
     *
     * @param course      课程数据
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置以专业数据
     * @param sysUserData 是否设置创建人数据
     * @return List<Course>
     */
    public Course setCourseExData(Course course, boolean teacherData, boolean subjectData, boolean sysUserData) {
        if (ObjectUtils.isNotEmpty(course)) {
            List<Course> courseList = new ArrayList<>();
            courseList.add(course);
            courseList = this.setCourseExData(courseList, teacherData, subjectData, sysUserData);
            course = courseList.get(0);
        }
        return course;
    }

    /**
     * 设置课程扩展数据
     *
     * @param courseList  课程数据列表
     * @param teacherData 是否设置讲师数据
     * @param subjectData 是否设置以专业数据
     * @param sysUserData 是否设置创建人数据
     * @return List<Course>
     */
    public List<Course> setCourseExData(List<Course> courseList, boolean teacherData, boolean subjectData, boolean sysUserData) {
        if (ObjectUtils.isNotEmpty(courseList)) {
            if (teacherData) {
                courseList = this.setCourseTeacherData(courseList, teacherData);
            }
            if (subjectData) {
                courseList = commonSetSubjectDataService.setSubjectData(subjectService, courseList, subjectData);
            }
            if (sysUserData) {
                courseList = commonSetCreateUserDataService.setSysUserData(sysUserService, courseList, sysUserData);
            }
            courseList = courseProfileBiz.setCourseProfileData(courseList,true);
        }
        return courseList;
    }

    /**
     * 设置课程讲师数据
     *
     * @param courseList  课程列表
     * @param teacherData 是否设置讲师数据，false不设置，true设置
     * @return List<Course>
     */
    private List<Course> setCourseTeacherData(List<Course> courseList, boolean teacherData) {
        if (ObjectUtils.isNotEmpty(courseList) && teacherData) {
            Map<Boolean, List<Course>> courseListMap = courseList.stream().collect(Collectors.groupingBy(e -> e.getCourseTypeKey().equals(CourseType.COURSE_TYPE_PACKAGE.getKey())));
            //普通课程列表
            List<Course> _courseList = courseListMap.get(false);
            if (ObjectUtils.isNotEmpty(_courseList)) {
                String teacherIds = _courseList.stream().filter(e -> StringUtils.isNotEmpty(e.getTeacherIds())).map(e -> e.getTeacherIds()).collect(Collectors.joining());
                teacherIds = StringUtils.subHeadTailString(teacherIds, ",").replaceAll(",,", ",").replaceAll(",,", ",");
                Map<BigDecimal, Map<String, Object>> sysTeacherMaps = sysTeacherService.findSysTeacherToMapByIds(teacherIds, false, false, false, false, false);
                if (ObjectUtils.isNotEmpty(sysTeacherMaps)) {
                    courseList.forEach(e -> {
                        List<Map<String, Object>> teacherList = new ArrayList<>();
                        String _teacherIds = e.getTeacherIds();
                        if (StringUtils.isNotEmpty(_teacherIds)) {
                            _teacherIds = StringUtils.subHeadTailString(_teacherIds, ",");
                            String[] arr = _teacherIds.split(",");
                            Arrays.stream(arr).forEach(em -> {
                                if(ObjectUtils.isNotEmpty(em)){
                                    Map<String, Object> teacherMap = sysTeacherMaps.get(new BigDecimal(em));
                                    if (ObjectUtils.isNotEmpty(teacherMap)) {
                                        teacherList.add(teacherMap);
                                    }
                                }

                            });
                        }
                        if (ObjectUtils.isNotEmpty(teacherList)) {
                            e.setTeacherList(teacherList);
                        }
                    });
                }
            }
            //套餐课程列表
            List<Course> packageCourseList = courseListMap.get(true);
            if (ObjectUtils.isNotEmpty(packageCourseList)) {
                String packageIds = packageCourseList.stream().map(e -> e.getId().toString()).collect(Collectors.joining(","));
                //获取套餐与课程的关联
                List<PackageCourse> _packageCourseList = packageCourseBiz.findPackageCourseByPackageIds(packageIds, false);
                if (ObjectUtils.isNotEmpty(_packageCourseList)) {
                    //得到所有套餐下的所有的课程ID串
                    String courseIds = _packageCourseList.stream().filter(e -> DataUtil.idIsNotNull(e.getCourseId())).map(e -> e.getCourseId().toString()).distinct().collect(Collectors.joining(","));
                    //查询课程，并设置课程的讲师
                    Map<BigDecimal, Course> courseMaps = this.findCourseToMapByIds(courseIds, true, false, false);
                    if (ObjectUtils.isNotEmpty(courseMaps)) {
                        //通过套餐ID分组
                        Map<BigDecimal, List<PackageCourse>> packageCourseListMap = _packageCourseList.stream().collect(Collectors.groupingBy(e -> e.getPackageId()));
                        packageCourseList.forEach(course -> {
                            //获取套餐下的的课程记录列表
                            List<PackageCourse> packageCourses = packageCourseListMap.get(course.getId());
                            //存储套餐下所有课程的讲师的Map
                            Map<BigDecimal, Map<String, Object>> teacherMap = new HashMap<>();
                            if (ObjectUtils.isNotEmpty(packageCourses)) {
                                packageCourses.forEach(packageCourse -> {
                                    if (packageCourse.getPackageType().intValue() == 1) {
                                        Course _course = courseMaps.get(packageCourse.getCourseId());
                                        if (ObjectUtils.isNotEmpty(_course)) {
                                            //获取课程下的讲师列表
                                            List<Map<String, Object>> teacherList = _course.getTeacherList();
                                            if (ObjectUtils.isNotEmpty(teacherList)) {
                                                teacherList.forEach(map -> {
                                                    BigDecimal teacherId = new BigDecimal(map.get("id").toString());
                                                    teacherMap.put(teacherId, map);
                                                });
                                            }
                                        }
                                    }
                                });
                            }
                            if (ObjectUtils.isNotEmpty(teacherMap)) {
                                List<Map<String, Object>> teacherList = new ArrayList<>();
                                teacherMap.forEach((k, v) -> {
                                    teacherList.add(v);
                                });
                                course.setTeacherList(teacherList);
                            }
                        });
                    }
                }
            }
        }
        return courseList;
    }





    private List<String> getColumnName(){
        return Arrays.asList("id","courseName","subjectIds","orPrice","realPrice","memberCourse","memberPrice","validType","validDay","validTime","courseTypeKey","teacherIds","courseNum","nodeNum","containNodeType","buyNum","testNum","useNum","allow","imageJson","contextStatus","studyLimit","scorePercent","year","createClass","createUserId","initBuyNum","status","summary","limitDate","openTime","endTime","audition");
    }

    /**
     * 查询课程总数量数据
     * @return CourseSumCount
     */
    public CourseSumCount queryCourseSumCount(){
        CourseSumCount courseSumCount = courseDao.queryCourseSumCount(Course.class);
        if(courseSumCount==null){
            courseSumCount = new CourseSumCount();
        }
        return courseSumCount;
    }

    public void updateCourseColumnNull(Map param){
        courseDao.updateCourseColumnNull(Course.class,param);
    }

    /**
     * 计算并获取课程总时长
     * @param courseId
     * @return
     */
    public Course durationSum( BigDecimal courseId) {
        Course course = this.findById(courseId);
        Integer oldTime = course.getTotleTimes()==null?0:course.getTotleTimes();
        List<CourseCatalog> courseCatalogs = courseCatalogBiz.findCourseCatalogByCourseId(courseId, false, false, false, false);
        int sum = courseCatalogs.stream().filter(e -> e != null && e.getVideoDuration() != null).mapToInt(e->e.getVideoDuration()).sum();
        Course entity = new Course();
        entity.setId(courseId);
        entity.setTotleTimes(sum);
        course.setTotleTimes(sum);
        this.updateById(entity,null);
        //判断如果当前修改的不是套餐,则更新所有引用该课程的套餐总时长
        if(!CourseType.COURSE_TYPE_PACKAGE.equals(course.getCourseTypeKey())){
            int differ = sum - oldTime;
            if(differ != 0){
                //查询所有拥有该课程的套餐,并修改套餐的总时长
                List<Course> packageCourses = courseDao.findPackageByCourseId(course.getId());
                packageCourses.stream().forEach(e->{
                    Integer totleTimes = e.getTotleTimes();
                    if(totleTimes == null){
                        totleTimes = 0;
                    }else{
                        totleTimes += differ;
                        if(totleTimes < 0){
                            totleTimes = 0;
                        }
                    }
                    e.setTotleTimes(totleTimes);
                });
                this.updateBatch(packageCourses);
            }
        }
        return course;
    }

}
